package com.tcoding.client.components.extend;

import com.jfoenix.controls.JFXPopup;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.base.IFXLabelFloatControl;
import com.jfoenix.controls.base.IFXValidatableControl;
import com.jfoenix.validation.base.ValidatorBase;
import com.tcoding.client.editor.CustomerBoxEditorModel;
import com.tcoding.core.entity.TestData;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * @author 唐全成
 * @Date: 2022/9/5 14:36
 * @description
 **/
@Data
public class JFXComboGrid extends HBox {

    private JFXPopup comboPopup;
    private JFXTextField comboTextField;
    private StackPane comboTablePane;
    private TableView<Map<String,Object>> tableView;
    private String value;
    private ObservableList<Map<String,Object>> items;
    private ComboGridConfig config;

    /**
     * Creates a VBox layout with spacing = 0 and alignment at TOP_LEFT.
     */
    public JFXComboGrid() {
        super();
    }

    /**
     * Creates a VBox layout with spacing = 0 and alignment at TOP_LEFT.
     */
    public JFXComboGrid(ComboGridConfig comboGridConfig) {
        super();
        super.setPadding(Insets.EMPTY);
        super.setWidth(comboGridConfig.getWidth());
        super.setMaxWidth(200);
        this.config = comboGridConfig;
        this.init();

    }

    private void init(){
        ObservableList<Map<String,Object>> innerList = FXCollections.observableArrayList();
        items = new SimpleListProperty<>(innerList);
        ComboGridConfig comboGridConfig = this.config;
        comboTextField = new JFXTextField();
        if(comboGridConfig.getWidth()!=null){
            comboTextField.setPrefWidth(comboGridConfig.getWidth());
        }
        comboTextField.setPromptText(comboGridConfig.getPlaceholder());
        comboTextField.setText(comboGridConfig.getText());
        comboTextField.setPrefHeight(20);
        this.value = comboGridConfig.getValue();

        comboTablePane = new StackPane();
        tableView = new TableView<>();
        tableView.setPrefHeight(300);
        tableView.getStyleClass().addAll("cf-table-view", "cf-scroll-bar-style");
        LinkedList<ComboGridTableColumn> columns = comboGridConfig.getColumns();
        for (ComboGridTableColumn comboGridTableColumn : columns) {
            TableColumn<Map<String,Object>,String> column= new TableColumn<>();
            column.setText(comboGridTableColumn.getText());
            column.setCellValueFactory(new MapValueFactory(comboGridTableColumn.getProp()));
            tableView.getColumns().add(column);
        }
        FilteredList<Map<String,Object>> filteredData = new FilteredList<>(items, p -> true);
        items.addAll(comboGridConfig.getItems());
        tableView.setItems(filteredData);


        tableView.getSelectionModel().selectedIndexProperty().addListener((observable,o,n)->{
            Map<String, Object> map = items.get(n.intValue());
            this.setValue(map.get(comboGridConfig.getTableValueColumn()).toString());
            this.comboTextField.setText(String.valueOf(map.get(this.getConfig().getTableTextColumn())));
            if(comboPopup.isShowing()){
                comboPopup.hide();
            }
        });


        comboTablePane.getChildren().add(tableView);
        comboPopup = new JFXPopup(comboTablePane);
        comboTablePane.setPrefWidth(comboGridConfig.getPopWidth()==null?300:comboGridConfig.getPopWidth());

        comboPopup.setOnShowing(comboGridConfig.getPopupShowing());
        comboPopup.setOnShown(comboGridConfig.getPopupShown());
//        comboTextField.focusedProperty().addListener((observable,o,n)->{
//            if(n){
//                comboPopup.show(comboTextField, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT,0,30);
//            }else {
//                if(comboPopup.isShowing()){
//                    comboPopup.hide();
//                }
//            }
//        });
        comboTextField.setOnMouseClicked(e->{
            comboPopup.show(comboTextField, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT,0,30);
        });

        EventHandler<KeyEvent> keyEventsHandler = t -> {
            if (t.getCode() == KeyCode.BACK_SPACE||t.getCode() == KeyCode.DELETE) {
                setValue("");
                comboTextField.setText("");
            }
        };
        comboTextField.setOnKeyPressed(keyEventsHandler);

        this.getChildren().add(comboTextField);
    }

    public void destroy(){
        comboPopup = null;
        comboTextField = null;
        comboTablePane = null;
        tableView = null;
    }


    public ComboGridConfig getConfig() {
        return config;
    }

    public void setConfig(ComboGridConfig config) {
        this.config = config;
        super.setHeight(40);
        super.setWidth(config.getWidth());
        super.setMaxWidth(200);
        this.init();
    }

    public String getValue() {
        if(this.config!=null&&this.config.getSetInputValue()&&StringUtils.isBlank(value)){
            return comboTextField.getText();
        }

        return value;
    }

    public void setValue(String value) {
        this.value = value;
        if(this.config.getItems()!=null&&this.config.getItems().size()>0&&StringUtils.isNotBlank(value)){

            Map<String, Object> toChoseItem =null;
            for (Map<String, Object> item : this.config.getItems()) {
                if(StringUtils.equals(value,item.get(this.config.getTableValueColumn()).toString())){
                    toChoseItem = item;
                    break;
                }
            }

            if(toChoseItem!=null){
                this.tableView.getSelectionModel().select(toChoseItem);
            }

        }
    }
}

